package com.fsd.core.util;


import com.sun.jndi.ldap.LdapCtx;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

/**
 * LDAP 认证
 */
public class LDAPAuthentication {

    private final String URL = "ldap://210.26.16.13:389/";
    private final String BASEDN = "dc=lzit";  // 根据自己情况进行修改
    private final String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
    private LdapContext ctx = null;
    private final Control[] connCtls = null;

    /**
     * 链接
     */
    public void LDAP_connect() throws Exception{
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
        env.put(Context.PROVIDER_URL, URL + BASEDN);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");

        String root = "cn=Manager,dc=lzit";  //根据自己情况修改
        env.put(Context.SECURITY_PRINCIPAL, root);   // 管理员
        env.put(Context.SECURITY_CREDENTIALS, "lzit1999");  // 管理员密码
        ctx = new InitialLdapContext(env, connCtls);
    }
    private void closeContext(){
        if (ctx != null) {
            try {
                ctx.close();
            }
            catch (NamingException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 获得用户
     * @param uid
     * @return
     */
    private String getUserDN(String uid) {
        String userDN = "";
        try {
            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

            NamingEnumeration<SearchResult> en = ctx.search("", "uid=" + uid, constraints);

            if (en == null || !en.hasMoreElements()) {
                System.out.println("未找到该用户");
            }
            // maybe more than one element
            while (en != null && en.hasMoreElements()) {
                Object obj = en.nextElement();
                if (obj instanceof SearchResult) {
                    SearchResult si = (SearchResult) obj;
                    userDN += si.getName();
                    userDN += "," + BASEDN;
                } else {
                    System.out.println(obj);
                }
            }
        } catch (Exception e) {
            System.out.println("查找用户时产生异常。");
            e.printStackTrace();
        }

        return userDN;
    }

    public List<Map<String, String>> getTeacherList(){
        try{
            NamingEnumeration<Binding> list = ctx.listBindings("ou=person");
            while (list.hasMoreElements()){
                Binding binding = list.nextElement();
                if(binding.getObject().getClass().equals(LdapCtx.class)){
                    if(binding.getName().equals("ou=campus")){
                        LdapCtx campusCtx = (LdapCtx) binding.getObject();

                        //老师部分
                        NamingEnumeration<Binding> teacherList = campusCtx.listBindings("ou=teacher");
                        List<Map<String, String>> teacnerResultList = new ArrayList<>();
                        while (teacherList.hasMoreElements()){
                            Binding teacherBinding = teacherList.nextElement();
                            if(teacherBinding.getObject().getClass().equals(LdapCtx.class)){
                                LdapCtx teacherCtx = (LdapCtx) teacherBinding.getObject();
                                Attributes attributes = teacherCtx.getAttributes("");

                                Map<String, String> teacherMap = new HashMap<String, String>();

                                teacherMap.put("xm", attributes.get("sn").get().toString());
                                teacherMap.put("sfzh",attributes.get("givenName").get().toString());
                                teacherMap.put("gh", attributes.get("uid").get().toString());
                                teacherMap.put("yx", attributes.get("ou").get().toString());
                                teacherMap.put("dzyj", attributes.get("mail").get().toString());
                                teacherMap.put("mm", attributes.get("userpassword").get().toString());

                                teacnerResultList.add(teacherMap);

//                                System.out.println("姓名：" + attributes.get("sn").get());
//                                System.out.println("身份证号：" + attributes.get("givenName").get());
//                                System.out.println("工号：" + attributes.get("uid").get());
//                                System.out.println("院系：" + attributes.get("ou").get());
//                                System.out.println("电子邮件：" + attributes.get("mail").get());
//                                System.out.println("密码：" + attributes.get("userpassword").get());
                            }
                        }
                        return teacnerResultList;
                    }
                }
            }

            closeContext();
        }catch (Exception e){
            closeContext();
            e.printStackTrace();
        }
        return null;
    }

    public List<Map<String, String>> getStudentList(){
        try{
            NamingEnumeration<Binding> list = ctx.listBindings("ou=person");
            while (list.hasMoreElements()){
                Binding binding = list.nextElement();
                if(binding.getObject().getClass().equals(LdapCtx.class)){
                    if(binding.getName().equals("ou=campus")){
                        LdapCtx campusCtx = (LdapCtx) binding.getObject();

                        //学生部分
                        NamingEnumeration<Binding> yearLis = campusCtx.listBindings("ou=student");
                        while (yearLis.hasMoreElements()){
                            Binding yearBinding = yearLis.nextElement();
                            if(yearBinding.getObject().getClass().equals(LdapCtx.class)){
                                LdapCtx yearCtx = (LdapCtx) yearBinding.getObject();
                                NamingEnumeration<Binding> tstudentList = yearCtx.listBindings("");
                                List<Map<String, String>> studentResultList = new ArrayList<>();
                                while (tstudentList.hasMoreElements()){
                                    Binding studentsBinding = tstudentList.nextElement();
                                    if(studentsBinding.getObject().getClass().equals(LdapCtx.class)){
                                        LdapCtx studentCtx = (LdapCtx) studentsBinding.getObject();
                                        Attributes attributes = studentCtx.getAttributes("");

                                        Map<String, String> studentMap = new HashMap<String, String>();
                                        studentMap.put("xm", attributes.get("sn").get().toString());
                                        studentMap.put("sfzh",attributes.get("givenName").get().toString());
                                        studentMap.put("xh", attributes.get("uid").get().toString());
                                        studentMap.put("bj", attributes.get("ou").get().toString());
                                        studentMap.put("dh", attributes.get("telephoneNumber").get().toString());
                                        studentMap.put("dzyj", attributes.get("mail").get().toString());
                                        studentMap.put("mm", attributes.get("userpassword").get().toString());

                                        studentResultList.add(studentMap);

//                                        System.out.println("姓名：" + attributes.get("sn").get().toString());
//                                        System.out.println("身份证号：" + attributes.get("givenName").get());
//                                        System.out.println("学号：" + attributes.get("uid").get());
//                                        System.out.println("班级：" + attributes.get("ou").get());
//                                        System.out.println("电话：" + attributes.get("telephoneNumber").get());
//                                        System.out.println("电子邮件：" + attributes.get("mail").get());
//                                        System.out.println("密码：" + attributes.get("userpassword").get());
                                    }

                                }
                                return studentResultList;
                            }
                        }
                    }
                }
            }

            closeContext();
        }catch (Exception e){
            closeContext();
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 认证
     * @param UID
     * @param password
     * @return
     */
    public boolean authenricate(String UID, String password) {
        boolean valide = false;
        String userDN = getUserDN(UID);

        try {
            ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
            ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
            ctx.reconnect(connCtls);
            System.out.println(userDN + " 验证通过");
            valide = true;
        } catch (AuthenticationException e) {
            System.out.println(userDN + " 验证失败");
            System.out.println(e.toString());
            valide = false;
        } catch (NamingException e) {
            System.out.println(userDN + " 验证失败");
            valide = false;
        }
        closeContext();
        return valide;
    }

    /**
     * 新增用户
     * @param usr
     * @param pwd
     * @return
     */
    private  boolean addUser(String usr, String pwd) {

        try {
            BasicAttributes attrsbu = new BasicAttributes();
            BasicAttribute objclassSet = new BasicAttribute("objectclass");
            objclassSet.add("inetOrgPerson");
            attrsbu.put(objclassSet);
            attrsbu.put("sn", usr);
            attrsbu.put("cn", usr);
            attrsbu.put("uid", usr);
            attrsbu.put("userPassword", pwd);
            ctx.createSubcontext("uid="+usr, attrsbu);

            return true;
        } catch (NamingException ex) {
            ex.printStackTrace();
        }
        closeContext();
        return false;
    }



    public static void main(String[] args) {
        try{
            LDAPAuthentication ldap = new LDAPAuthentication();
            ldap.LDAP_connect();
            List<Map<String, String>> list = ldap.getTeacherList();

            for(int i=0;i<list.size();i++){
                //将对象内容转换成string
                Map<String, String> obj = list.get(i);
                if("汽车工程学院".equals(obj.get("yx"))){
                    System.out.println(obj.get("xm"));
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }

//        if(ldap.authenricate("2016010947", "2016010947")){
//            System.out.println("验证通过");
//        }
//        ldap.getUserDN("yorker");

//        if(ldap.authenricate("yorker", "secret") == true){
//
//            System.out.println( "该用户认证成功" );
//
//        }
        //ldap.addUser("czj333","123456");

    }
}
